package com.novanok.campaigntweets;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.novanok.mensaje.Mensaje;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import twitter4j.FilterQuery;
import twitter4j.StallWarning;
import twitter4j.Status;
import twitter4j.StatusDeletionNotice;
import twitter4j.StatusListener;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterStream;
import twitter4j.TwitterStreamFactory;
import twitter4j.User;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;


public class MyActivity extends Activity {

    private static final String TAG = "MyActivity.java";

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private String[] mPlanetTitles;
    private ActionBarDrawerToggle mDrawerToggle;
    private View vistaSeleccionada;
    private TwitterStream twitterStream = new TwitterStreamFactory().getInstance();
    private boolean procesa;
    private long cantidadTweetsTrackeados = 0;

    public static ArrayList<Campania> listaCampania = null;
    public static Campania campaniaSeleccionada = null;

    private static String token;
    private static String tokenSecret;

    @Override
    protected void onCreate( Bundle savedInstanceState ) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_my );

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        if ( listaCampania == null )
            listaCampania = new ArrayList<Campania>();

        mPlanetTitles = getResources().getStringArray( R.array.menu );
        mDrawerLayout = ( DrawerLayout ) findViewById( R.id.drawer_layout );
        mDrawerList = ( ListView ) findViewById( R.id.left_drawer );

        mDrawerLayout.setDrawerShadow( R.drawable.drawer_shadow, GravityCompat.START );
        mDrawerList.setAdapter( new ArrayAdapter<String>( this, R.layout.drawer_list_item, mPlanetTitles ) );
        mDrawerList.setOnItemClickListener( new DrawerItemClickListener() );

        mDrawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description for accessibility */
                R.string.drawer_close  /* "close drawer" description for accessibility */
        ) {
            public void onDrawerClosed( View view ) {
                super.onDrawerClosed(view);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            public void onDrawerOpened( View drawerView ) {
                super.onDrawerOpened( drawerView );
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };

        mDrawerLayout.setDrawerListener( mDrawerToggle );
        getActionBar().setDisplayHomeAsUpEnabled( true );
        getActionBar().setHomeButtonEnabled( true );

        leerObjetos();
        setClickLista();
        iniciarActualizacionValores();


        twitterStream.setOAuthConsumer( TwitterUtil.getConsumerKey(), TwitterUtil.getConsumerSecret() );
        StatusListener listener = new StatusListener() {
            @Override
            public void onStatus( final Status status ) {
                MyActivity.this.cantidadTweetsTrackeados++;

                // Log.d( TAG, status.getText().trim() );

                synchronized ( listaCampania ) {
                    for ( Campania c : listaCampania )
                        if ( c.isProcesa() )
                            c.verificarTweetConPalabras( status );
                }
            }

            @Override
            public void onDeletionNotice( StatusDeletionNotice statusDeletionNotice ) {
                System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId());
            }

            @Override
            public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
                System.out.println("Got track limitation notice:" + numberOfLimitedStatuses);
            }

            @Override
            public void onScrubGeo(long userId, long upToStatusId) {
                System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId);
            }

            @Override
            public void onStallWarning( StallWarning warning ) {
                System.out.println("Got stall warning:" + warning);
            }

            @Override
            public void onException( Exception ex ) {
                ex.printStackTrace();
            }
        };

        twitterStream.addListener( listener );

        Uri uri = getIntent().getData();
        String verifier = uri.getQueryParameter( "oauth_verifier" );
        new TwitterGetAccessTokenTask().execute( verifier );
    }

    private void iniciar(){
        if ( twitterStream != null ){
            ( ( TextView ) findViewById( R.id.lblEstado ) ).setText("Cerrando el Streaming...");

            twitterStream.shutdown();
            try {
                Thread.sleep( 10000 );
            } catch ( InterruptedException e ) {
                e.printStackTrace();
            }
        }

        twitterStream.setOAuthAccessToken( new AccessToken( token, tokenSecret ) );
        double[][] locations = { { -180, -90 }, { 180, 90 } };
        FilterQuery fill = new FilterQuery();
        fill.locations( locations );

        twitterStream.filter( fill );
        ( ( TextView ) findViewById( R.id.lblEstado ) ).setText("Iniciando el Streaming...");

/*
        ArrayList<String> palabras = new ArrayList<String>();

        for ( Campania c : listaCampania )
            for ( Palabra p : c.getPalabras() )
                palabras.add( p.getDescripcion().trim() );

        FilterQuery fill = new FilterQuery();
        String[] pala = new String[ palabras.size() ];
        pala = palabras.toArray( pala );

        fill.track( pala );
*/
    }

    private void iniciarActualizacionValores(){
        this.procesa = true;

        new Thread(new Runnable() {
            @Override
            public void run() {
                while( MyActivity.this.procesa ){
                    try {
                        MyActivity.this.runOnUiThread(new Runnable() {
                            public void run() {
                                ( ( TextView ) findViewById( R.id.lblEstado ) ).setText( "Cantidad de Tweets Trackeados : " + MyActivity.this.cantidadTweetsTrackeados );

                                (( ListaCampaniasAdapter )( ( ListView ) findViewById( R.id.lstPalabras ) ).getAdapter()).notifyDataSetChanged();
                            }
                        });

                        Thread.sleep( 5000 );
                    } catch ( InterruptedException e ) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    private void iniciarActualizacionDatosPerfil() {
        final boolean procesaDatosPerfil = true;
        final Twitter tw = TwitterUtil.getInstance().getTwitter();
        tw.setOAuthAccessToken(new AccessToken( MyActivity.getAccessToken(), MyActivity.getAccessTokenSecret() ));

        new Thread(new Runnable() {
            @Override
            public void run() {
                while( procesaDatosPerfil ){
                    try {
                        MyActivity.this.runOnUiThread(new Runnable() {
                            public void run() {
                                User usuario;
                                try {
                                    usuario = tw.verifyCredentials();
                                    ((TextView)findViewById(R.id.lblCantidadSeguidores)).setText("SEGUIDORES \n" + usuario.getFollowersCount());
                                    ((TextView)findViewById(R.id.lblCantidadAmigos)).setText("AMIGOS \n" + usuario.getFriendsCount());
                                    ((TextView)findViewById(R.id.lblCantidadTweets)).setText("TWEETS \n" + usuario.getStatusesCount());
                                    ((TextView)findViewById(R.id.lblCantidadFavoritos)).setText("FAVORITOS \n" + usuario.getFavouritesCount());

                                } catch (TwitterException e) {
                                    e.printStackTrace();
                                }
                            }
                        });

                        Thread.sleep( 90000 );
                    } catch ( InterruptedException e ) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    public void verTweets ( View v ){
        ListaCampaniasAdapter adapter = ( ListaCampaniasAdapter )( ( ListView ) findViewById( R.id.lstPalabras ) ).getAdapter();
        campaniaSeleccionada = adapter.getItem( ( ( ListView ) findViewById( R.id.lstPalabras ) ).getPositionForView( v ) );

        Intent i = new Intent(this, ActivityTweet.class);
        startActivity(i);
    }

    public void editar ( View v ){
        ListaCampaniasAdapter adapter = ( ListaCampaniasAdapter )( ( ListView ) findViewById( R.id.lstPalabras ) ).getAdapter();
        campaniaSeleccionada = adapter.getItem( ( ( ListView ) findViewById( R.id.lstPalabras ) ).getPositionForView( v ) );

        Intent i = new Intent(this, ActivityCampania.class);
        startActivity(i);
    }

    public void verPalabras ( View v ){
        ListaCampaniasAdapter adapter = ( ListaCampaniasAdapter )( ( ListView ) findViewById( R.id.lstPalabras ) ).getAdapter();
        campaniaSeleccionada = adapter.getItem( ( ( ListView ) findViewById( R.id.lstPalabras ) ).getPositionForView( v ) );

        Intent i = new Intent(this, ActivityPalabra.class);
        startActivity(i);
    }

    public void verUsuariosAExcluir ( View v ){

    }

    public void iniciarCampania( View v ){
        ListaCampaniasAdapter adapter = ( ListaCampaniasAdapter )( ( ListView ) findViewById( R.id.lstPalabras ) ).getAdapter();
        Campania c = adapter.getItem( ( ( ListView ) findViewById( R.id.lstPalabras ) ).getPositionForView( v ));

        if ( c.getTweets().size() == 0){
            Mensaje.getMensaje().mostrarInformacion(this, "No se configuraron los Tweets a Enviar para la Campaña :(");
            return;
        }

        if ( c.getPalabras().size() == 0 ){
            Mensaje.getMensaje().mostrarInformacion(this, "No se configuraron las Palabras a Trackear para la Campaña :(");
            return;
        }

        if ( !c.isAlive() ) {
            c.iniciar();
            this.vistaSeleccionada = (View)v.getParent();

            if ( this.vistaSeleccionada != null ){
                this.vistaSeleccionada.findViewById(R.id.btnIniciarCampania).setVisibility(View.INVISIBLE);
                this.vistaSeleccionada.findViewById(R.id.btnDetenerCampania).setVisibility(View.VISIBLE);
            }
        }
    }

    public void detenerCampania( View v ){
        ListaCampaniasAdapter adapter = ( ListaCampaniasAdapter )( ( ListView ) findViewById( R.id.lstPalabras ) ).getAdapter();
        Campania c = adapter.getItem( ( ( ListView ) findViewById( R.id.lstPalabras ) ).getPositionForView( v ));
        c.detener();

        this.vistaSeleccionada = (View)v.getParent();

        if ( this.vistaSeleccionada != null ){
            this.vistaSeleccionada.findViewById( R.id.btnIniciarCampania ).setVisibility( View.VISIBLE );
            this.vistaSeleccionada.findViewById( R.id.btnDetenerCampania ).setVisibility( View.INVISIBLE );
        }
    }

    private void leerObjetos(){
        FileInputStream fis;

        try {
            listaCampania = new ArrayList<Campania>();

            fis = this.openFileInput("campania_tweets_data");
            ObjectInputStream is = new ObjectInputStream( fis );
            Campania c;

            while ( ( c = ( Campania ) is.readObject() ) != null ){
                listaCampania.add( c );
            }

            is.close();
        } catch ( FileNotFoundException e ) {
            e.printStackTrace();

        } catch ( IOException e ) {
            e.printStackTrace();

        } catch ( ClassNotFoundException e ) {
            e.printStackTrace();

        }
    }

    private void setClickLista(){
        ListView lv = ( ListView ) findViewById( R.id.lstPalabras );

        lv.setOnItemClickListener( new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick( AdapterView<?> adapterView, View view, int i, long l ) {
                view.setSelected( true );
                MyActivity.this.vistaSeleccionada = view;
            }
        });
    }

    public void onResume(){
        super.onResume();
        ( ( ListView ) MyActivity.this.findViewById( R.id.lstPalabras ) ).setAdapter(new ListaCampaniasAdapter(MyActivity.this, listaCampania));
    }

    public void onDestroy(){
        super.onDestroy();
        guardar();
    }

    private void guardar(){
        FileOutputStream fos;

        try {
            fos = this.openFileOutput( "campania_tweets_data", MODE_PRIVATE );
            ObjectOutputStream os = new ObjectOutputStream( fos );

            for ( Campania c : listaCampania )
                os.writeObject(c);

            os.close();
        } catch ( FileNotFoundException e ) {
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onOptionsItemSelected( MenuItem item ) {
        int id = item.getItemId();

        if ( id == R.id.action_settings ) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void eliminarCampania ( View v ){
        ListaCampaniasAdapter adapter = ( ListaCampaniasAdapter )( ( ListView ) findViewById( R.id.lstPalabras ) ).getAdapter();

        Object toRemove = adapter.getItem( ( ( ListView ) findViewById( R.id.lstPalabras ) ).getPositionForView( v ));
        if ( toRemove != null ) {
            listaCampania.remove(toRemove);
            adapter.notifyDataSetChanged();
        }
    }

    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick( AdapterView<?> parent, View view, int position, long id ) {
            selectItem( position );
        }
    }

    private void selectItem( int position ) {
        mDrawerList.setItemChecked( position, true );
        mDrawerLayout.closeDrawer( mDrawerList );

        switch ( position ){
            case 0:{
                campaniaSeleccionada = null;
                Intent i = new Intent(this, ActivityCampania.class);
                startActivity(i);
                break;
            }

            case 1:{
                guardar();
                break;
            }
        }
    }

    public static String getAccessToken (){
        return token;
    }

    public static String getAccessTokenSecret(){
        return tokenSecret;
    }

    class TwitterGetAccessTokenTask extends AsyncTask<String, String, String> {

        @Override
        protected void onPostExecute( String userName ) {
            iniciar();
            iniciarActualizacionDatosPerfil();
        }

        @Override
        protected String doInBackground( String... params ) {

            Twitter twitter = TwitterUtil.getInstance().getTwitter();
            RequestToken requestToken = TwitterUtil.getInstance().getRequestToken();

            try {
                AccessToken accessToken = twitter.getOAuthAccessToken( requestToken, params[0] );
                token = accessToken.getToken();
                tokenSecret = accessToken.getTokenSecret();
            } catch ( TwitterException e ) {
                e.printStackTrace();
            }
            return null;
        }
    }
}
